﻿//-----------------------------------------------------------------------------------------------------------
// Wbfs Engine (WBFSe) Project by Omega Frost 
// http://wbfse.codeplex.com/
//
// WBFSe is Licensed under the terms of the 
// Microsoft Reciprocal License (Ms-RL)
//-----------------------------------------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WBFSe.IO;
using WBFSe.IO.Drives;
using System.IO;

namespace WBFSe
{
    /// <summary>
    /// Device controller
    /// </summary>
    static class WbfsDevices
    {
        const int NumDrives = 26; // A ~ Z
        // Variables

        private static IWbfsDriveInfo[] Drives =
            new IWbfsDriveInfo[NumDrives];

        // Methods

        /// <summary>
        /// Returns the drive corresponding to a path
        /// </summary>
        /// <param name="path">Path</param>
        /// <returns>Drive</returns>
        /// <exception cref="System.Exception">On operation failure</exception>
        internal static IWbfsDriveInfo GetDrive(String path)
        {
            path = Path.GetFullPath(path);
            int idx = (int)(Char.ToUpper(path[0]) - 'A');
            IWbfsDriveInfo drive = Drives[idx];

            if ((drive != null) && drive.IsReady)
            {
                return drive;
            }

            DriveInfo di = new DriveInfo(path);
            if (di.DriveType == DriveType.NoRootDirectory)
            {
                Drives[idx] = null;
                return null;
            }

            if (di.IsReady)
            {
                drive = new OSDrive(di);
                Drives[idx] = drive;
                return drive;
            }

            WbfsDrive.Open(di, out drive);
            Drives[idx] = drive;

            return drive;
        }

        /// <summary>
        /// Formats a drive as WBFS
        /// </summary>
        /// <param name="path">Destination drive</param>
        /// <returns>Formatted drive</returns>
        internal static IWbfsDriveInfo FormatAsWbfs(string path)
        {
            path = Path.GetFullPath(path);
            int idx = (int)(Char.ToUpper(path[0]) - 'A');
            IWbfsDriveInfo drive = Drives[idx];

            if ((drive != null) && drive.IsReady)
                drive.Close();

            if (!WbfsDrive.Format(new DriveInfo(path), out drive))
                throw new ArgumentException("Invalid drive");

            Drives[idx] = drive;
            return drive;
        }

        /// <summary>
        /// Swaps the drives in the array
        /// </summary>
        /// <param name="a">Original</param>
        /// <param name="b">Destination</param>
        internal static void Swap(IWbfsDriveInfo a, IWbfsDriveInfo b)
        {
            int idx = (int)(Char.ToUpper(a.Name[0]) - 'A');
            Drives[idx] = b;
        }
    }
}
